package cn.goour.web.sys.service

import cn.goour.web.base.`interface`.ServiceBase
import cn.goour.web.base.entity.PageInfo
import cn.goour.web.base.exception.BackJsonBeanValidFailException
import cn.goour.web.sys.entity.Admin
import cn.goour.web.sys.entity.Log
import cn.goour.web.sys.repository.AdminRepository
import cn.goour.web.sys.repository.LogRepository
import decrypt
import encrypt
import getAdmin
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import org.springframework.stereotype.Service
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
import javax.annotation.PostConstruct
import javax.persistence.criteria.CriteriaBuilder
import javax.persistence.criteria.CriteriaQuery
import javax.persistence.criteria.Root
import javax.security.auth.login.LoginException
import javax.transaction.Transactional

@Service
@Transactional
open class AdminService : ServiceBase<Admin>/*UserDetailsService*/ {
    @Autowired private
    lateinit var adminRepository: AdminRepository
    @Autowired private
    lateinit var roleService: RoleService
    @Autowired private
    lateinit var logRepository: LogRepository

    /*
        @Throws(UsernameNotFoundException::class)
        override fun loadUserByUsername(p0: String): UserDetails {
            val admin = adminRepository.getByUsername1(p0) ?: throw UsernameNotFoundException("用户名不存在")
            logger.info("当前的用户角色：${admin.roles}")
            val list = ArrayList<Role>()
            admin.roles.forEach {
                list.add(it)
                list.addAll(roleService.getSubAllRole(it))
            }
            admin.roles = list
            logger.info("重新获取的用户角色：${admin.roles}")
            logger.info(admin.toString())
            return admin
        }

        @PreAuthorize("hasAnyRole('ADMIN')")
        open fun getAA(): String {
            return "sd"
        }
    */
    open fun findOne(id: Int): Admin? = adminRepository.findOne(id)

    @Throws(LoginException::class)
    open fun getLogin(admin: Admin): Admin {
        val re = adminRepository.getByUsername(admin.username)
        if (re != null) {
            val request = (RequestContextHolder.getRequestAttributes() as ServletRequestAttributes).request
            if (re.login) {
                if (re.password.decrypt() == admin.password) {
                    val log = Log(admin = re, actionText = "登录成功", request = request)
                    logRepository.save(log)
                    return re
                } else {
                    val log = Log(admin = re, actionText = "登录失败，密码错误，尝试密码：${admin.password}", request = request)
                    logRepository.save(log)
                    throw LoginException("密码错误")
                }
            } else {
                val log = Log(admin = re, actionText = "登录失败，帐号不允许登录", request = request)
                logRepository.save(log)
                throw LoginException("不允许登录")
            }
        } else {
            throw LoginException("没有找到用户")
        }
    }

    open fun getList(pageInfo: PageInfo): Page<Admin>? {
        val request = (RequestContextHolder.getRequestAttributes() as ServletRequestAttributes).request
        val pageRequest = PageRequest(pageInfo.page - 1, pageInfo.size, Sort(Sort.Order(Sort.Direction.ASC, "id")))

        return adminRepository.findAll({ root: Root<Admin>, _: CriteriaQuery<*>, criteriaBuilder: CriteriaBuilder ->
            val n1 = criteriaBuilder.notEqual(root.get<Int>("vip"), 0)// 不显示超级管理员
            val n2 = criteriaBuilder.notEqual(root.get<Int>("id"), request.getAdmin().id)//不显示当前用户
            if (pageInfo.search.isBlank()) {
                criteriaBuilder.and(n1, n2)
            } else {
                val search = pageInfo.search
                val c1 = criteriaBuilder.like(root.get("name"), "%$search%")
                val c2 = criteriaBuilder.like(root.get("email"), "%$search%")

                val c3 = criteriaBuilder.like(root.get("username"), "%$search%")
                criteriaBuilder.and(n1, n2, criteriaBuilder.or(c1, c2, c3))
            }
        }, pageRequest)
    }

    override fun add(vo: Admin): Admin {
        vo.password = vo.password.encrypt()
        val find = adminRepository.getByUsername(vo.username) ?: return adminRepository.save(vo)
        throw BackJsonBeanValidFailException("系统中已经存在该登录名");
    }

    override fun update(vo: Admin) {
        adminRepository.saveAndFlush(vo)
    }

    override fun delete(ids: Array<Int>) {
        ids.forEach {
            adminRepository.delete(it)
        }
    }

    init {
        logger.info("Initialized ${this.javaClass.simpleName}...")
    }

    @PostConstruct
    fun post() {
        logger.info("PostConstruct ${this.javaClass.simpleName}...")
    }

    companion object {
        private val logger = LoggerFactory.getLogger(AdminService::class.java)
    }
}